import {VUE_CLICK_OUTSIDE} from "../../types";
import {getSelfElementsIdList, getTargetParentElement} from "@/vue-taro-click-outside/help";

/**
 * @method v-taro-click-outside:[arg]="handleFun"
 * @description vue taro 框架开发小程序页面元素外部点击事件
 * @param arg: {key:value}动态参数传参,非必传，默认获取小程序当前页面顶级page元素
 * 若需要获取特定父级元素，则可配置如 arg: {targetParentNodeName:'root', parentNodePropName:‘class’, parentNodePropValue:'className'}
 * targetParentNodeName：目标父级节点元素
 * parentNodePropName：目标元素节点的查找属性
 * parentNodePropValue：目标节点元素查找的属性值
 * 一般 v-taro-click-outside="clickOutsideHandle" 即可满足使用
 * */

export const vueTaroClickOutside: VUE_CLICK_OUTSIDE = {
    inserted(el: any, binding: any){
        el.targetParentNodeName = binding.arg?.targetParentNodeName || 'root';
        const  parentNodePropName = binding.arg?.parentNodePropName;
        const parentNodePropValue = binding.arg?.parentNodePropValue;
        // 获取元素自身及所以字节点id
        el = getSelfElementsIdList({el: el, currentNode: el});
        // 获取目标父级元素节点
        el = getTargetParentElement({
            el: el,
            currentNode: el,
            nodeName: 'root',
            parentNodePropName: parentNodePropName,
            parentNodePropValue: parentNodePropValue
        });
        // 事件处理方法
        function eventHandler(event: Event) {
            // @ts-ignore
            const currentId = event?.target?.id;
            // 判断事件是否元素本身或其子元素节点触发
            if(el.elementIdList.includes(currentId)){
                return false;
            }
            if(binding.expression) {
                binding.value(event);
            }
        }
        // 目标元素事件绑定
        el.__clickOutside__ = eventHandler;
        if(el.targetParentEventNode) {
            // el.targetParentEventNode.__clickOutside__ = eventHandler;
            el.targetParentEventNode.addEventListener('tap', eventHandler);
        } else {
            // el.targetParentNode.__clickOutside__ = eventHandler;
            el.targetParentNode.addEventListener('tap', eventHandler);
        }
    },
    unbind(el: any) {
        // 解绑，解除监听
        if (el.targetParentEventNode) {
            el.targetParentEventNode.removeEventListener('tap', el.__clickOutside__);
        } else {
            el.targetParentNode.removeEventListener('tap', el.__clickOutside__);
        }
        delete el.targetParentNode;
        delete el.targetParentEventNode;
        delete el.targetParentNodeName;
        delete el.elementIdList;
    }
}
//
// // 获取元素节点id， 统计元素本身所以子节点id
// function getSelfElementsIdList(el: any, currentNode: any): void{
//     if(!el.elementIdList) el.elementIdList = [];
//     if(!el.elementIdList.includes(currentNode.uid)) el.elementIdList.push(currentNode.uid);
//     // 判断字节的
//     if(currentNode.childNodes.length){
//         for(let childNode of currentNode.childNodes) {
//             getSelfElementsIdList(el, childNode);
//         }
//     }
// }
// // 获取当前所在页面顶级元素 TaroElement
// function getTargetParentElement(options: ITargetParentElementOptions) {
//     const el = options?.el;
//     let currentNode = options?.currentNode;
//     const nodeName = options?.nodeName;
//     const parentNodePropName = options?.parentNodePropName;
//     const parentNodePropValue = options?.parentNodePropValue;
//     if(parentNodePropName && parentNodePropValue) {
//         while(currentNode && currentNode.props[parentNodePropName] !== parentNodePropValue){
//             if(currentNode.parentNode){
//                 currentNode = currentNode.parentNode;
//             }
//         }
//         if(currentNode) {
//             el.targetParentNode = currentNode;
//         }
//     } else {
//         // TaroElement虚拟节点
//         // nodeName: root > block > container > body > html > #document
//         // tagName: ROOT > BLOCK > CONTAINER > BODY > HTML > #DOCUMENT
//         while (currentNode && currentNode.nodeName !== nodeName) {
//             if (currentNode.parentNode) {
//                 currentNode = currentNode.parentNode;
//             }
//             // 当nodeName为 'root‘时
//             // 默认目标父级元素节点，taro小程序对应<page></page>元素节点，当前页面实际顶级父级元素节点为其字节的
//             if(currentNode.parentNode.nodeName === nodeName && 'root' === nodeName) {
//                 el.targetParentEventNode = currentNode;
//             }
//         }
//         if(currentNode) {
//             el.targetParentNode = currentNode;
//         }
//     }
//     return el;
// }
